package com.ooono.factorytest.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.Log;
import android.view.View;

import com.ooono.factorytest.R;

public class CircleAnimaView extends View {
    private static final String TAG = "CircleAnimaView";

    // scale of circle
    public static final float RADIANS_STEP = (float) (2 * Math.PI) / 200;
    // initial scale.it draw from right endpoint by default,you can control where start drawing by assigning it.
    // for example you can start draw from left endpoint by assigning it -Math.PI
    private float startRadians = 0;
    // recorde the max/min radians had been drawed
    private float minEndRadians = 0;
    private float maxEndRadians = 0;
    private float currentEndRadians = 0;

    private Paint paint;

    private float outsideRadius;
    private float insideRadius;
    private float ballRadius;

    // coordinate of circle
    private float[] circleCoords;

    // coordinate of ball
    private float[] ballCoords;

    private boolean isBallTouchCircle = false;

    private int highLightColor;

    private boolean isDetectedComplete = false;

    public CircleAnimaView(Context context) {
        super(context);
        // painter to paint line
        paint = new Paint();
        paint.setStyle(Paint.Style.FILL);
        paint.setStrokeWidth(3);
        paint.setAntiAlias(true);// set anti alias
        paint.setFlags(Paint.ANTI_ALIAS_FLAG);// help to set anti alias

        outsideRadius = getResources().getDimensionPixelSize(R.dimen.gyro_outside_diameter) / 2;
        Log.d(TAG, "outsideRadius=" + outsideRadius);
        insideRadius = outsideRadius - 50;
        ballRadius = 50;

        // point(0,0) is not coordinate of circle but center of canvas.
        // we should know that the origin of coordinates of the canvas is top left corner
        circleCoords = new float[]{outsideRadius, outsideRadius};
        ballCoords = circleCoords;

        highLightColor = context.getResources().getColor(R.color.gray);
    }

    protected void onDraw(Canvas canvas) {
        float[] startXY, endXY;
        float radians;

        // in some time,the green circle dosen't draw complete depend on isDetectedComplete(),
        // so just draw a green circle
        if (isDetectedComplete) {
            radians = startRadians;
            paint.setColor(highLightColor);
            while (radians < 2 * Math.PI + startRadians) {
                startXY = CoordsCalc.calcArcEndPointXY(circleCoords[0],
                        circleCoords[1], outsideRadius, radians);
                endXY = CoordsCalc.calcArcEndPointXY(circleCoords[0],
                        circleCoords[1], insideRadius, radians);
                canvas.drawLine(startXY[0], startXY[1], endXY[0], endXY[1], paint);
                radians += RADIANS_STEP;
            }
            canvas.drawCircle(ballCoords[0], ballCoords[1], ballRadius, paint);
            return;
        }


        // draw white circle
        radians = startRadians;
        paint.setColor(Color.WHITE);
        while (radians < 2 * Math.PI + startRadians) {
            startXY = CoordsCalc.calcArcEndPointXY(circleCoords[0],
                    circleCoords[1], outsideRadius, radians);
            endXY = CoordsCalc.calcArcEndPointXY(circleCoords[0],
                    circleCoords[1], insideRadius, radians);
            canvas.drawLine(startXY[0], startXY[1], endXY[0], endXY[1], paint);
            radians += RADIANS_STEP;
        }

        // draw green circle
        if (isBallTouchCircle) {
            paint.setColor(highLightColor);
            // draw green circle towards clockwise
            radians = startRadians;
            while (radians < maxEndRadians) {
                startXY = CoordsCalc.calcArcEndPointXY(circleCoords[0],
                        circleCoords[1], outsideRadius, radians);
                endXY = CoordsCalc.calcArcEndPointXY(circleCoords[0],
                        circleCoords[1], insideRadius, radians);
                canvas.drawLine(startXY[0], startXY[1], endXY[0], endXY[1],
                        paint);
                radians += RADIANS_STEP;
            }
            // // draw green circle towards anti-clockwise
            radians = startRadians;
            while (radians > minEndRadians) {
                startXY = CoordsCalc.calcArcEndPointXY(circleCoords[0],
                        circleCoords[1], outsideRadius, radians);
                endXY = CoordsCalc.calcArcEndPointXY(circleCoords[0],
                        circleCoords[1], insideRadius, radians);
                canvas.drawLine(startXY[0], startXY[1], endXY[0], endXY[1],
                        paint);
                radians -= RADIANS_STEP;
            }
        }

        if (isBallTouchCircle) {
            // draw a ball at current end point
            paint.setColor(highLightColor);
            ballCoords = CoordsCalc.calcArcEndPointXY(circleCoords[0],
                    circleCoords[1], insideRadius - ballRadius,
                    currentEndRadians);
            canvas.drawCircle(ballCoords[0], ballCoords[1], ballRadius, paint);
        } else {
            paint.setColor(highLightColor);
            canvas.drawCircle(ballCoords[0], ballCoords[1], ballRadius, paint);
        }
    }

    /**
     * @param radians radians need to draw
     */
    public void setGreenCircleEndRadians(float radians) {
        currentEndRadians = radians + startRadians;
        if (currentEndRadians > maxEndRadians) {
            maxEndRadians = currentEndRadians;
        }
        if (currentEndRadians < minEndRadians) {
            minEndRadians = currentEndRadians;
        }
        invalidate();
    }

    public float getInsideRadius() {
        return insideRadius;
    }

    public float getBallRadius() {
        return ballRadius;
    }

    public float[] getCircleCoords() {
        return circleCoords;
    }

    public void setBallCoords(float[] ballCoords) {
        this.ballCoords = ballCoords;
        invalidate();
    }

    public void setStartRadians(float startRadians) {
        this.startRadians = startRadians;
        minEndRadians = startRadians;
        maxEndRadians = startRadians;
    }

    public void setIsBallTouchCircle(boolean isBallTouchCircle) {
        this.isBallTouchCircle = isBallTouchCircle;
    }

    /**
     * If gyroscope detected completely or not(If the green circle draw completely or not)
     *
     * @return Return true if the gyroscope detected completely(The green circle draw completely),else return false
     */
    public boolean isDetectedComplete() {
        isDetectedComplete = Math.abs((maxEndRadians - minEndRadians) - 2 * Math.PI) < 2 * RADIANS_STEP ? true : false;
        return isDetectedComplete;
    }
}
